/*******************************************************************************
*                                    ZLG
*                         ----------------------------
*                         innovating embedded platform
*
* Copyright (c) 2001-2021 Guangzhou ZHIYUAN Electronics Co., Ltd.
* All rights reserved.
*
* Contact information:
* web site:    https://www.zlg.cn
*******************************************************************************/
#ifndef __HC32F4A0_USART_H__
#define __HC32F4A0_USART_H__

#ifdef __cplusplus
extern "C" {
#endif  /* __cplusplus*/
#include "core/include/hc32f4a0_regs_usart.h"
#include "core/include/hc32f4a0_regs_gpio.h"
#include "driver/gpio/hc32f4a0_gpio.h"
#include "common/hc32f4a0_common.h"

/* \brief USART 标志*/
#define USART_FLAG_PE                 (USART_SR_PE)       /* 校验错误标志 */
#define USART_FLAG_FE                 (USART_SR_FE)       /*!< Framing error flag */
#define USART_FLAG_ORE                (USART_SR_ORE)      /* 过流错误标志 */
#define USART_FLAG_BE                 (USART_SR_BE)       /*!< LIN bus error flag */
#define USART_FLAG_RXNE               (USART_SR_RXNE)     /* 接收数据寄存器非空标志*/
#define USART_FLAG_TC                 (USART_SR_TC)       /* 传输完成标志 */
#define USART_FLAG_TXE                (USART_SR_TXE)      /* 传输数据寄存器空标志 */
#define USART_FLAG_RTOF               (USART_SR_RTOF)     /* 接收超时标志*/
#define USART_FLAG_LBD                (USART_SR_LBD)      /*!< LIN break signal detection flag */
#define USART_FLAG_WKUP               (USART_SR_WKUP)     /*!< LIN wakeup signal detection flag */
#define USART_FLAG_MPB                (USART_SR_MPB)      /* 接收处理器ID标志*/

/* \brief USART 清除标志*/
#define USART_CLEAR_FLAG_PE           (USART_CR1_CPE)     /* 清除校验错误标志 */
#define USART_CLEAR_FLAG_FE           (USART_CR1_CFE)     /*!< Clear Framing error flag */
#define USART_CLEAR_FLAG_ORE          (USART_CR1_CORE)    /* 清除过流错误标志 */
#define USART_CLEAR_FLAG_RTOF         (USART_CR1_CRTOF)   /* 清除接收超时标志 */
#define USART_CLEAR_FLAG_BE           (USART_CR1_CBE)     /*!< Clear LIN bus error flag */
#define USART_CLEAR_FLAG_WKUP         (USART_CR1_CWKUP)   /*!< Clear LIN wakeup signal flag */
#define USART_CLEAR_FLAG_LBD          (USART_CR1_CLBD)    /*!< Clear LIN break detection flag */

/* \brief USART 传输/接收功能*/
#define USART_RX                      (USART_CR1_RE)      /* USART RX 功能 */
#define USART_TX                      (USART_CR1_TE)      /* USART TX 功能 */
#define USART_RTO                     (USART_CR1_RTOE)    /* USART RX 超时功能 */
#define USART_INT_RX                  (USART_CR1_RIE)     /* USART 接收数据寄存器非空且接收错误中断 */
#define USART_INT_TXE                 (USART_CR1_TXEIE)   /* USART 传输数据寄存器空中断 */
#define USART_INT_TC                  (USART_CR1_TCIE)    /* USART 传输完成中断 */
#define USART_INT_RTO                 (USART_CR1_RTOIE)   /* USART RX 超时中断 */

/* \brief USART时钟分频系数*/
#define USART_PCLK_DIV1               (0UL)               /* PCLK 不分频 */
#define USART_PCLK_DIV4               (USART_PR_PSC_0)    /* PCLK 4 分频 */
#define USART_PCLK_DIV16              (USART_PR_PSC_1)    /* PCLK 16 分频 */
#define USART_PCLK_DIV64              (USART_PR_PSC)      /* PCLK 64 分频 */

/* \brief USART 控制寄存器2保留位9/10定义，需保持复位值 11b,写 入时写 入时11b*/
#define USART_CR2_BIT9                (0x00000200UL)
#define USART_CR2_BIT10               (0x00000400UL)

/* \brief USART 停止位*/
#define USART_STOPBIT_1BIT            (0UL)               /* 1位停止位*/
#define USART_STOPBIT_2BIT            (USART_CR2_STOP)    /* 2位停止位*/

/* \brief USART 时钟模式选择*/
#define USART_EXTCLK                  (USART_CR2_CLKC_1)  /* 外部时钟源*/
#define USART_INTERNCLK_OUTPUT        (USART_CR2_CLKC_0)  /* 选择内部时钟源和输出时钟*/
#define USART_INTERNCLK_NONE_OUTPUT   (0UL)               /* 选择内部时钟源不输出时钟*/

/* \brief USART 数据位宽度*/
#define USART_DATA_LENGTH_8BIT        (0UL)               /* 8 位*/
#define USART_DATA_LENGTH_9BIT        (USART_CR1_M)       /* 9 位 */

/* \brief USART 校验*/
#define USART_PARITY_NONE             (0UL)                          /* 无校验*/
#define USART_PARITY_EVEN             (USART_CR1_PCE)                /* 偶校验*/
#define USART_PARITY_ODD              (USART_CR1_PCE | USART_CR1_PS) /* 奇校验*/

/* \brief USART 硬件流控制*/
#define USART_HWFLOWCTRL_NONE         (0UL)               /* 关闭USART硬件流控制*/
#define USART_HWFLOWCTRL_RTS          (USART_CR3_RTSE)    /* USART硬件流控制RTS模式*/
#define USART_HWFLOWCTRL_CTS          (USART_CR3_CTSE)    /* USART硬件流控制CTS模式*/
#define USART_HWFLOWCTRL_RTS_CTS      (USART_CR3_RTSE | USART_CR3_CTSE) /* USART硬件流控制CTS和RTS模式 */

/* \brief USART 过采样模式*/
#define USART_OVERSAMPLING_16BIT      (0UL)               /* 16位*/
#define USART_OVERSAMPLING_8BIT       (USART_CR1_OVER8)   /* 8位*/

/* \brief USART 数据大小端*/
#define USART_LSB                     (0UL)               /* 小端*/
#define USART_MSB                     (USART_CR1_ML)      /* 大端*/

/* \brief USART 数字滤波使能位*/
#define USART_NOISE_FILTER_DISABLE    (0UL)               /* 关闭*/
#define USART_NOISE_FILTER_ENABLE     (USART_CR1_NFE)     /* 使能*/

/* \brief USART 模式接收数据开始位检测方式设定位*/
#define USART_SB_DETECT_LOW           (0UL)               /* 开始检测方式为RX管脚低电平*/
#define USART_SB_DETECT_FALLING       (USART_CR1_SBS)     /* 开始检测方式为RX管脚下降沿*/


/* \brief USART 驱动配置*/
struct usart_cfg {
    uint32_t baudrate;             /* 波特率，当时钟源是 PCLK 时有效*/
    uint32_t clk_mode;             /* 时钟模式 */
    uint32_t pclk_div;             /* PCLK 分频，当时钟源是 PCLK 时有效 */
    uint32_t parity;               /* 校验模式 */
    uint32_t data_width;           /* 数据宽度 */
    uint32_t stop_bit;             /* 停止位 */
    uint32_t oversampling_bits;    /* Oversampling Bits */
    uint32_t bit_direction;        /* 有效位 */
    uint32_t noise_filter_state;   /* RX pin noise filter state */
    uint32_t sb_detect_polarity;   /* Start Bit Detect Polarity */
    uint32_t hw_flow_ctrl;         /* 硬件控制流 */
};


/**
 * \brief USART 初始化
 *
 * \param[in] p_usart_reg USART 寄存器
 * \param[in] p_cfg       USART 配置
 *
 * \retval 成功返回 0
 */
int usart_init(struct hc32f4a0_usart_reg *p_usart_reg, struct usart_cfg *p_cfg);
/**
 * \brief USART 反初始化
 *
 * \param[in] p_usart_reg USART 寄存器
 */
void usart_deinit(struct hc32f4a0_usart_reg *p_usart_reg);
/**
 * \brief USART 启动
 *
 * \param[in] p_usart_reg USART 寄存器
 *
 * \retval 成功返回 0
 */
int usart_start(struct hc32f4a0_usart_reg *p_usart_reg);
/**
 * \brief USART 停止
 *
 * \param[in] p_usart_reg USART 寄存器
 *
 * \retval 成功返回 0
 */
int usart_stop(struct hc32f4a0_usart_reg *p_usart_reg);
/**
 * \brief USART 波特率设置
 *
 * \param[in]  p_usart_reg USART 串口寄存器
 * \param[in]  baudrate    要设置的波特率
 * \param[out] p_err       返回错误
 *
 * \retval 成功返回 0
 */
int usart_baudrate_set(struct hc32f4a0_usart_reg *p_usart_reg,
                       uint32_t                   baudrate,
                       float                     *p_err);
/**
 * \brief USART 字节读函数
 *
 * \param[in] p_usart_reg USART 寄存器
 * \param[in] p_data      要接收的字节数据缓存
 *
 * \retval 成功返回 1
 */
int usart_byte_read(struct hc32f4a0_usart_reg *p_usart_reg, uint8_t *p_data);
/**
 * \brief USART 发送函数
 *
 * \param[in] p_usart_reg USART 寄存器
 * \param[in] data        要发送的字节数据
 *
 * \retval 成功返回 1
 */
int usart_byte_write(struct hc32f4a0_usart_reg *p_usart_reg, uint8_t data);
#ifdef __cplusplus
}
#endif  /* __cplusplus  */
#endif





